package pip.can;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

import org.jgraph.JGraph;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.GraphConstants;

import org.jgrapht.ListenableGraph;
import org.jgrapht.demo.JGraphAdapterDemo;
import org.jgrapht.event.GraphEdgeChangeEvent;
import org.jgrapht.event.GraphListener;
import org.jgrapht.event.GraphVertexChangeEvent;
import org.jgrapht.ext.JGraphModelAdapter;
import org.jgrapht.graph.ListenableDirectedGraph;
import org.jgrapht.graph.DefaultEdge;

import pip.can.NetGraph.RelationshipEdge;

 
public class NetGraph extends JApplet {
    private static final Color     DEFAULT_BG_COLOR = Color.decode( "#FAFBFF" );
    private static final Dimension DEFAULT_SIZE = new Dimension( 530, 320 );
    private int nodeNum = 7;
    private  ListenableGraph g;
    // 
    private JGraphModelAdapter m_jgAdapter;
    private JGraph jgraph;
    private JComboBox comboBox;
    /**
     * @see java.applet.Applet#init().
     */
    public NetGraph(int type) {
        // create a JGraphT graph
         g = new ListenableDirectedGraph( DefaultEdge.class );
        
        // create a visualization using JGraph, via an adapter
        m_jgAdapter = new JGraphModelAdapter( g );
        jgraph = new JGraph( m_jgAdapter );
        jgraph.setEditable(false);
      //jgraph.getSelectionCell();
        //jgraph.setSize(579, 300);
        adjustDisplaySettings( jgraph );
        getContentPane(  ).add( jgraph );
        JButton jb = new JButton("Dodaj węzeł");
        jb.setBounds(10, 40, 130, 25);
        comboBox = new JComboBox();
		comboBox.setModel(new DefaultComboBoxModel(new String[] {"10 mbps", "20 mbps", "30 mbps"}));
		comboBox.setBounds(10, 70, 130, 25);
        JButton jbRemove = new JButton("Usuń");
        jbRemove.setBounds(10, 10, 130, 25);
        jb.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				String name = "Node"+Integer.toString(nodeNum);
				nodeNum++;
				g.addVertex(name);
				g.addEdge( name, name,comboBox.getSelectedItem().toString());
				positionVertexAt( name,20, 200 );	
				StaticVariables.pathCap.put(name, (comboBox.getSelectedIndex()+1)*10);
			}
		});
        jbRemove.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Object selected = jgraph.getSelectionCell();
				if (selected!=null){
					System.out.println(selected.toString());
					if(g.containsVertex(selected.toString()))
						g.removeVertex(selected.toString());
					else if(g.containsEdge(selected.toString()))
						g.removeEdge(selected.toString());
					//jgraph.
				}
			}
		});
        jgraph.add(comboBox);
        jgraph.add(jb);
        jgraph.add(jbRemove);
        //resize( 579, 300 );
        //jgraph.setSize(579, 300);
        // add some sample data (graph manipulated via JGraphT)
        if(type == 0){
        	linearNetwork();
        }
        else if(type ==1 ){
        	treeNetwork();
        }
        else{
        	
        }

       
    }
    public JGraph getGraph(){
    	return jgraph;
    }
    public ListenableGraph getG(){
    	return g;
    }
    
    public void linearNetwork(){
    	g.addVertex( "Repository" );
        g.addVertex( "Clients" );
        g.addVertex( "Node1" );
        g.addVertex( "Node2" );
        g.addVertex( "Node3" );
        
        
        g.addEdge( "Clients", "Node3",new RelationshipEdge<String>("Node1", "Clients", "30 mbps") );
        g.addEdge( "Node3", "Node2",new RelationshipEdge<String>("Node2", "Node1", "20 mbps") );
        g.addEdge( "Node2", "Node1",new RelationshipEdge<String>("Node3", "Node2", "10 mbps") );
        g.addEdge( "Node1", "Repository",new RelationshipEdge<String>("Repository", "Node3", "30 mbps") );


        // position vertices nicely within JGraph component
        positionVertexAt( "Clients",300, 280 );
        positionVertexAt( "Node3", 300, 210 );
        positionVertexAt( "Node2", 300, 140 );
        positionVertexAt( "Node1", 300, 70 );
        positionVertexAt( "Repository", 300, 0 );
    }
    
    public void removeAll(){
    	Set edges = new HashSet(g.edgeSet());
    	g.removeAllEdges(edges);
    	Set v = new HashSet(g.vertexSet());
    	g.removeAllVertices(v);
    }
    
    public void treeNetwork(){
        g.addVertex( "Repository" );
        g.addVertex( "Clients1" );
        g.addVertex( "Clients2" );
        g.addVertex( "Clients3" );
        g.addVertex( "Clients4" );
        //lvl 1
        g.addVertex( "Node1" );
        g.addVertex( "Node2" );
        //lvl2
        g.addVertex( "Node3" );
        g.addVertex( "Node4" );
        g.addVertex( "Node5" );
        g.addVertex( "Node6" );
        
        g.addEdge( "Node1", "Repository",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Node2", "Repository",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Node3", "Node1",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Node4", "Node1",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Node5", "Node2",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Node6", "Node2",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Clients1", "Node3",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Clients2", "Node4",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Clients3", "Node5",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        g.addEdge( "Clients4", "Node6",new RelationshipEdge<String>("Repository", "Node3", "20 mbps") );
        // position vertices nicely within JGraph component
        positionVertexAt( "Repository", 240, 0 );
        positionVertexAt( "Node1", 75, 70 );
        positionVertexAt( "Node2", 375, 70 );
        positionVertexAt( "Node3", 0, 140 );
        positionVertexAt( "Node4", 150, 140 );
        positionVertexAt( "Node5", 300, 140 );
        positionVertexAt( "Node6", 450, 140 );
        positionVertexAt( "Clients1", 0, 230 );
        positionVertexAt( "Clients2", 150, 230 );
        positionVertexAt( "Clients3", 300, 230 );
        positionVertexAt( "Clients4", 450, 230 );

    }

    private void adjustDisplaySettings( JGraph jg ) {
        jg.setPreferredSize( DEFAULT_SIZE );

        Color  c        = DEFAULT_BG_COLOR;
        String colorStr = null;

        try {
            colorStr = getParameter( "bgcolor" );
        }
         catch( Exception e ) {}

        if( colorStr != null ) {
            c = Color.decode( colorStr );
        }

        jg.setBackground( c );
    }

    private void positionAt( Object vertex, int x, int y, int h, int w ) {
        DefaultGraphCell cell = m_jgAdapter.getVertexCell( vertex );
        Map              attr = cell.getAttributes(  );
        Rectangle2D        b    = GraphConstants.getBounds( attr );
        GraphConstants.setBounds( attr, new Rectangle( x, y, w, h ) );

        Map cellAttr = new HashMap(  );
        cellAttr.put( cell, attr );
        m_jgAdapter.edit( cellAttr, null, null, null );
    }
    
    private void positionVertexAt( Object vertex, int x, int y ) {
        DefaultGraphCell cell = m_jgAdapter.getVertexCell( vertex );
        Map              attr = cell.getAttributes(  );
        Rectangle2D        b    = GraphConstants.getBounds( attr );
        GraphConstants.setBounds( attr, new Rectangle( x, y, b.getBounds().width, b.getBounds().height ) );

        Map cellAttr = new HashMap(  );
        cellAttr.put( cell, attr );
        m_jgAdapter.edit( cellAttr, null, null, null );
    }
    
    public static class RelationshipEdge<V> extends DefaultEdge {
        private V v1;
        private V v2;
        private String label;

        public RelationshipEdge(V v1, V v2, String label) {
            this.v1 = v1;
            this.v2 = v2;
            this.label = label;
        }

        public V getV1() {
            return v1;
        }

        public V getV2() {
            return v2;
        }

        public String toString() {
            return label;
        }
    }
}
